#include <iostream> // библиотке ввода-вывода
#include <string> // библиотека строк
#include <vector> // библиотека векторов (динамических массивов без ограничений памяти)

using namespace std;

class Page {
    string page_title;
    string page_text;
    vector <string> page_words;

    public:

    vector <string> transform_text_to_words(string file_text){
        vector <string> words; // массив для хранения слов строки (используется вектор для устранения ограничения на размер памяти)
        string word = "";

        for (int i = 0; i <= file_text.size(); i++) { // цикл на прохождение строки
            if (!(isspace(file_text[i]) || ispunct(file_text[i]) || file_text[i] == '\0')){
                word.push_back(file_text[i]);
                continue;
            }
            if (word.empty())
                continue;
            words.push_back(word);
            word.clear();
        }

        return words; // возвращаем отсортированный массив
    }

    void input_title(string title){
        page_title = title;
    }

    void input_text(string text){
        page_text = text;
        page_words = transform_text_to_words(page_text);
    }

    void delete_target_word(string target_word){
        string new_text = "";

        for (int i = 0; i < page_words.size(); i++){
            if (target_word == page_words[i])
                continue;
            new_text.append(page_words[i]);
            new_text.append(" ");
        }

        page_text = new_text;
    }

    string get_text(){
        return page_text;
    }

    string get_title(){
        return page_title;
    }

    int get_count_target_word(string target_word){
        int count = 0;

        for (int i = 0; i < page_words.size(); i++){
            if (page_words[i] == target_word){
                count++;
            }
        }

        return count;
    }
};

class Book {
    vector <Page> pages;
    vector <int> count_target_word_in_pages;

    static int books_number;

    public:

    void input_pages_size(int size){
        pages.resize(size);
        count_target_word_in_pages.resize(size);
    }

    void input_pages(){
        string title = "";
        string text = "";

        for (int i = 0; i < pages.size(); i++){
            cout << "\n\n\t\tInput " << i+1 << " page's title: ";
            getline(cin, title);
            pages[i].input_title(title);

            cout << "\n\t\tInput " << i+1 << " page's text:\n\n\t\t\t";
            getline(cin, text);
            pages[i].input_text(text);
        }
    }

    void output_pages(){
        for (int i = 0; i < pages.size(); i++){
            cout << "\n\n\t\t" << i+1 << " page's title: " << pages[i].get_title();
            cout << "\n\t\t" << i+1 << " page's text:\n\n\t\t\t" << pages[i].get_text();
        }
    }

    void delete_target_word(string target_word, int page_index){
        pages[page_index].delete_target_word(target_word);
    }

    int get_count_target_word(string target_word){
        int count = 0;

        for (int i = 0; i < pages.size(); i++){
            count_target_word_in_pages[i] = pages[i].get_count_target_word(target_word);
        }

        for (int i = 0; i < count_target_word_in_pages.size(); i++){
            count += count_target_word_in_pages[i];
        }

        return count;
    }

    int get_book_size(){
        return pages.size();
    }
};

class Library {
    int pages_size;

    int book_index = -1;
    int book_max;

    vector <Book> libre;
    vector <int> count_target_word_in_library;

    public:

    Library(int size){
        libre.resize(size);
        count_target_word_in_library.resize(size);
        cout << "Constructor " << this << " initialized\n";
    }

    void input_library(){
        for (int i = 0; i < libre.size(); i++){
            cout << "\n\tInput " << i+1 << " book page's quantity: ";
            cin >> pages_size;
            cin.get();
            cout << endl;

            libre[i].input_pages_size(pages_size);
            libre[i].input_pages();
        }
    }

    void output_library(){
        cout << "\n\nOutput lybrary";

        for (int i = 0; i < libre.size(); i++){
            cout << "\n\n\t" << i+1 << " book:";
            libre[i].output_pages();
        }

        cout << "\n\n";
    }

    int get_book_index(string target_word){
        for (int i = 0; i < libre.size(); i++){
            count_target_word_in_library[i] = libre[i].get_count_target_word(target_word);
        }

        book_max = count_target_word_in_library[0];
        for (int i = 0; i < libre.size(); i++){
            if (book_max <= count_target_word_in_library[i]){
                book_max = count_target_word_in_library[i];
                book_index = i;
            }
        }

        if (book_max == 0)
            book_index = -1;

        return book_index;
    }

    bool check_page_exist(int page_index){
        return (page_index >= 0 && page_index < libre[book_index].get_book_size());
    }

    void delete_target_word(string target_word, int page_index){
        libre[book_index].delete_target_word(target_word, page_index);
    }

    ~Library(){
        cout << "Destructor " << this << " initialized\n";
    }
};

int main(){
    int books_size;
    int book_index;
    int page_index;
    
    string target_word;

    
    system("clear");

    // system("cowsay -t \"Привет, это программа для задания 2.1. Пожайлуста не ломайте её лишний раз, я итак уже вскрылся, пока её писал.\"");
    // system("sleep 10 && clear");

    // system("jp2a Armstrong-profile.jpg --colors&& echo \"\nNanomachines, son!\n© Senator Armstrong\"");
    // system("sleep 6 && clear");
    
    // system("jp2a ukr-bomb.jpg --colors && echo \"\nУкрасинька бимба.\n© Хохланд\"");
    // system("sleep 4 && clear");

    // system("jp2a glasses.jpg --colors && echo \"\nКазах без понтов - беспонтовый казах.\n© Неизвестный\"");
    // system("sleep 4 && clear");
    
    cout << "Input library size: ";
    cin >> books_size;
    cin.get();
    cout << endl;

    if (books_size < 1){
        cout << "\nLibrary's size can't be less than 1.\n";
        return 0;
    }

    Library *lib = new Library(books_size);

    (*lib).input_library();

    cout << "\n\nInput target word: ";
    cin >> target_word;
    cin.get();
    cout << endl;

    book_index = (*lib).get_book_index(target_word);

    if (book_index == -1){
        cout << "\nInputed word doesn't find.\n";
        return 0;
    }

    cout << "\nIndex of found book: " << book_index + 1 << endl;

    cout << "\n\nInput book's page: ";
    cin >> page_index;
    cin.get();
    cout << endl << endl;

    if (!((*lib).check_page_exist(page_index - 1))){
        cout << "Inputed index page doesn't exist.\n";
        return 0;
    }

    (*lib).delete_target_word(target_word, page_index - 1);

    (*lib).output_library();

    delete lib;

    return 0;
}